<template>
  <div class="zero-code-list">
    <vxe-grid
      v-if="!grid.loading"
      v-bind="grid"
      ref="xGrid"
      :cellStyle="cellStyle"
    >
      <template #toolbar_buttons>
        <listToolbarButtons
          :zeroCodeId="zeroCodeId"
          :menuId="menuId"
          :settingJson="settingJson"
          @click="buttonClick"
        >
        </listToolbarButtons>
      </template>

      <template #toolbar_tools> </template>

      <template #loading>
        <a-spin></a-spin>
      </template>

      <template #empty>
        <eip-empty />
      </template>

      <template #checkboxHeader="{ checked, indeterminate }">
        <span @click.stop="$refs.xGrid.toggleAllCheckboxRow()">
          <a-checkbox :indeterminate="indeterminate" :checked="checked">
          </a-checkbox>
        </span>
      </template>
      <!-- 多选 -->
      <template #checkbox="{ row, checked, indeterminate }">
        <span @click.stop="$refs.xGrid.toggleCheckboxRow(row)">
          <a-checkbox :indeterminate="indeterminate" :checked="checked">
          </a-checkbox>
        </span>
      </template>
      <!-- 单选 -->
      <template #radio="{ row, checked }">
        <span @click.stop="$refs.xGrid.toggleCheckboxRow(row)">
          <a-radio :checked="checked"> </a-radio>
        </span>
      </template>
      <!-- 序号 -->
      <template #seq="">
        <span>序号</span>
      </template>
      <template #seqdefalut="{ row }">
        <div
          v-if="
            cellStyle({ row }) && [0, 1].includes(cellStyle({ row }).showType)
          "
          class="flex justify-between align-center"
        >
          <span> {{ row.row_num }}</span>
          <span
            class="colorTag"
            :style="{
              'background-color': cellStyle({ row }).showTypeColor,
            }"
          >
          </span>
        </div>
        <span v-else>
          {{ row.row_num }}
        </span>
      </template>
      <!-- 格式化内容 -->
      <template #default="{ row, column }">
        <list-content
          :row="row"
          :column="column"
          :type="convertType(column)"
          :options="getOptions(column)"
        ></list-content>
      </template>
    </vxe-grid>
    <worksheet
      ref="worksheet"
      v-if="worksheet.visible"
      :visible.sync="worksheet.visible"
      :options="{
        rowId: worksheet.rowId,
        rowIds: worksheet.rowIds,
        zeroCodeId: worksheet.zeroCodeId,
        mode: worksheet.mode,
        from: worksheet.from,
      }"
      @ok="reloadData"
    ></worksheet>
  </div>
</template>

<script>
import { mapMutations, mapGetters } from "vuex";
import { findById, viewPublic } from "@/services/system/zerocode/view/designer";
import {
  query,
  del,
  copy,
  gridCustomFindByKey,
  gridCustomSave,
} from "@/services/system/zerocode/run/list";
import { selectTableRow, deleteConfirm } from "@/utils/util";
import listContent from "./components/list/content";
import listToolbarButtons from "./components/list/buttons";
import worksheet from "./worksheet";
import { VxeUI } from "vxe-pc-ui";
import { newGuid } from "../../../../utils/util";
export default {
  data() {
    return {
      view: {
        menuId: this.menuId,
        zeroCodeId: this.zeroCodeId,
      },
      grid: {
        loading: true,
      }, //列表配置
      publicJson: {}, //发布配置
      columnJson: {}, //字段配置
      settingJson: {},
      //编辑组件
      worksheet: {
        zeroCodeId: null,
        rowId: null,
        visible: false,
        rowIds: [],
        mode: null,
        from: {
          zeroCodeId: null, //工作表
          key: null, //来源控件(用于区分双向关联才解析默认绑定)
          rowId: null, //来源数据RowId,从列表上来时为多个，逗号分割
          button: null, //来源按钮,有值则表示从按钮点击来
        },
      },
      refreshDataInterval: null,

      gridCustom: {
        fixedData: null,
        resizableData: null,
        sortData: null,
        visibleData: null,
      },
    };
  },
  props: {
    //低代码Id
    zeroCodeId: {
      type: String,
    },
    //菜单Id
    menuId: {
      type: String,
    },
    //名称
    name: {
      type: String,
    },
    //模式:0操作，1设计
    mode: {
      type: Number,
      default: 0,
    },
    //设计模式的长度,若是只有一个标签就不显示标签了
    modeLength: {
      type: Number,
      default: 0,
    },
  },
  //关闭摧毁
  beforeDestroy() {
    if (this.refreshDataInterval) {
      clearInterval(this.refreshDataInterval);
    }
  },
  watch: {
    //若有改变则赋予属性
    zeroCodeId(val) {
      if (val) {
        this.initGrid();
        this.reloadData();
      }
    },
  },
  components: {
    worksheet,
    listContent,
    listToolbarButtons,
  },

  created() {
    this.initGrid();
  },
  computed: {
    ...mapGetters("account", ["zeroCode"]),
  },
  methods: {
    ...mapMutations("account", ["setZeroCode"]),

    /**
     *初始化列表配置项
     */
    async initGridOption() {
      let that = this;
      //默认排序
      let option = this.publicJson;
      let zeroCodeId = this.zeroCodeId;
      let title = this.$route.name;
      let columns = await that.initColumn();
      this.grid = {
        size: option.style.size,
        border: option.style.border,
        stripe: option.style.stripe,
        id: "xGrid",
        loading: true,
        height:
          this.eipTableHeight() -
          (this.mode == 0 && this.modeLength == 1
            ? 0
            : this.mode == 0
            ? 38
            : 90),
        sortConfig: {
          trigger: "cell",
          defaultSort: this.initSorts(),
          orders: ["desc", "asc", null],
          remote: true,
          multiple: true,
          chronological: true,
        },
        checkboxConfig: {
          reserve: true,
        },
        radioConfig: {
          reserve: true,
        },
        expandConfig: {
          reserve: true,
        },
        rowConfig: {
          keyField: "RowId",
        },
        customConfig: {
          storage: true,
          mode: "popup",
          restoreStore({ storeData }) {
            return true;
          },
          updateStore({ id, type, storeData }) {
            let resizableData = that.$utils.merge(
              that.gridCustom.resizableData,
              storeData.resizableData
            );
            let fixedData = that.$utils.merge(
              that.gridCustom.fixedData,
              storeData.fixedData
            );
            let sortData = that.$utils.merge(
              that.gridCustom.sortData,
              storeData.sortData
            );
            let visibleData = that.$utils.merge(
              that.gridCustom.visibleData,
              storeData.visibleData
            );
            gridCustomSave({
              key: zeroCodeId,
              title: title,
              config: JSON.stringify({
                fixedData: fixedData,
                resizableData: resizableData,
                sortData: sortData,
                visibleData: visibleData,
              }),
            }).then((result) => {});
            return true;
          },
        },
        pagerConfig: {},
        printConfig: {},
        exportConfig: {},
        filterConfig: {
          remote: true,
        },
        toolbarConfig: {
          slots: {
            buttons: "toolbar_buttons",
            tools: "toolbar_tools",
          },
        },
        columns: columns,
        proxyConfig: {
          seq: true,
          sort: true,
          filter: true,
          props: {
            result: "data",
            total: "count",
          },
          ajax: {
            query: ({ page, sorts, filters }) => {
              if (sorts.length == 0) {
                //再次找默认
                sorts = this.initSorts();
              }
              var gridSort = this.eipGridSort(sorts);
              return new Promise((resolve) => {
                query({
                  zeroCodeId: this.zeroCodeId,
                  current: page.currentPage,
                  size: page.pageSize,
                  rote: {
                    menuId: this.menuId,
                  },
                  timeStamp: option.style.cache
                    ? null
                    : this.$utils.timestamp(), //时间戳:可通过设置该值达到不读取缓存数据效果
                  sort: gridSort ? gridSort : "id desc",
                  filters: this.eipTableFilter(filters),
                }).then((result) => {
                  if (result.code == this.eipResultCode.success) {
                    this.worksheet.rowIds = result.data.data.map(
                      (m) => m.RowId
                    );

                    resolve(result.data);
                  } else {
                    this.$message.error(result.msg);
                    resolve({
                      data: [],
                    });
                  }
                  this.initDataInterval();
                });
              });
            },
          },
        },
      };

      that.grid.loading = false;
    },

    /**
     * 初始化列表
     */
    initGrid() {
      let that = this;
      VxeUI.loading.open();
      findById(this.zeroCodeId).then((result) => {
        that.publicJson = that.$utils.merge(
          that.$utils.clone(that.eipZeroCodeView, true),
          that.$utils.toStringJSON(result.data.publicJson)
        );
        that.settingJson = JSON.parse(result.data.settingJson);
        that.columnJson = JSON.parse(result.data.columnJson);
        that.worksheet.zeroCodeId = result.data.formZeroCodeId;
        that.initGridOption();
        VxeUI.loading.close();
      });
    },

    /**
     * 初始化列
     */
    async initColumn() {
      let that = this;
      let option = this.publicJson;
      let data = option.field.data;
      data = option.field.data.filter((f) => f.check);

      let columns = [];

      data.forEach((element) => {
        let columnFind = that.$utils.find(
          that.columnJson,
          (f) => f.key == element.key
        );
        let column = {
          field: element.key,
          title: element.label,
          width: element.width,
          sortable: true,
          slots: {},
          showOverflow: "ellipsis",
          filterRender: {
            name: "MLFilterRender",
          },
          filters: [
            {
              data: {
                type: "input",
                key: null,
                op: "cn",
                write: null,
                options: [],
              },
            },
          ],
        };
        //处理格式化
        if (columnFind) {
          switch (columnFind.type) {
            case that.eipZeroCodeControl.radio:
            case that.eipZeroCodeControl.checkbox:
            case that.eipZeroCodeControl.select:
              let options = [];
              columnFind.options.options.forEach((element) => {
                options.push({
                  value: element.value,
                  label: element.label,
                  checked: false,
                  color: columnFind.options.optionsColor ? element.color : null,
                });
              });
              column.filters = [
                {
                  data: {
                    type: "select",
                    key: null,
                    op: "jcn",
                    write: null,
                    options: options,
                  },
                },
              ];
              break;
            case that.eipZeroCodeControl.number:
              column.filters = [
                {
                  data: {
                    type: "number",
                    op: "cn",
                    write: null,
                    min: null,
                    max: null,
                  },
                },
              ];
              break;
            case that.eipZeroCodeControl.switch:
              column.filters = [
                {
                  data: {
                    type: "switch",
                    key: null,
                    op: "cn",
                    write: null,
                    options: [
                      {
                        value: 1,
                        label: "是",
                        checked: false,
                        color: "red",
                      },
                      {
                        value: 0,
                        label: "否",
                        checked: false,
                        color: "#1890ff",
                      },
                    ],
                  },
                },
              ];
              break;
            case that.eipZeroCodeControl.rate:
              column.filters = [
                {
                  data: {
                    type: "number",
                    op: "cn",
                    write: null,
                    min: null,
                    max: null,
                  },
                },
              ];
              break;
            case that.eipZeroCodeControl.slider:
              column.filters = [
                {
                  data: {
                    type: "number",
                    op: "cn",
                    write: null,
                    min: null,
                    max: null,
                  },
                },
              ];
              break;
            case that.eipZeroCodeControl.uploadFile:
            case that.eipZeroCodeControl.uploadImg:
              break;
            case that.eipZeroCodeControl.editor:
              column.type = "html";
              break;
            case that.eipZeroCodeControl.date:
              column.filters = [
                {
                  data: {
                    type: "datetime",
                    op: "cn",
                    write: null,
                    min: null,
                    max: null,
                  },
                },
              ];
              break;
          }
          if (columnFind.type != that.eipZeroCodeControl.editor) {
            column.slots.default = "default";
          }
          columns.push(column);
        }

        //判断是否为系统字段
        switch (element.key) {
          case "CreateTime":
          case "UpdateTime":
            column.filters = [
              {
                data: {
                  type: "datetime",
                  op: "cn",
                  write: null,
                  min: null,
                  max: null,
                },
              },
            ];
            columns.push(column);
            break;
          case "RowId":
            column.filters = [
              {
                data: {
                  type: "input",
                  key: null,
                  op: "cn",
                  write: null,
                  options: [],
                },
              },
            ];
            columns.push(column);
            break;
          case "CreateUser":
          case "UpdateUser":
            column.filters = [
              {
                data: {
                  type: "user",
                  op: "cn",
                  write: null,
                },
              },
            ];
            column.slots.default = "default";
            columns.push(column);
            break;
        }
      });

      //获取grid
      var gridCustom = await gridCustomFindByKey(this.zeroCodeId);
      if (gridCustom.data != null && gridCustom.data.config != null) {
        var config = JSON.parse(gridCustom.data.config);
        if (config.resizableData) {
          var resizableDataKey = that.$utils.keys(config.resizableData);
          resizableDataKey.forEach((key) => {
            var columnsFind = that.$utils.find(columns, (f) => f.field == key);
            if (columnsFind) {
              columnsFind.width = config.resizableData[key];
            }
          });
          that.gridCustom.resizableData = config.resizableData;
        }
        //固定
        if (config.fixedData) {
          var fixedDataKey = that.$utils.keys(config.fixedData);
          fixedDataKey.forEach((key) => {
            var columnsFind = that.$utils.find(columns, (f) => f.field == key);
            if (columnsFind) {
              columnsFind.fixed = config.fixedData[key];
            }
          });
          that.gridCustom.fixedData = config.fixedData;
        }
        //隐藏显示
        if (config.visibleData) {
          var visibleDataKey = that.$utils.keys(config.visibleData);
          visibleDataKey.forEach((key) => {
            var columnsFind = that.$utils.find(columns, (f) => f.field == key);
            if (columnsFind) {
              columnsFind.visible = config.visibleData[key];
            }
          });
          that.gridCustom.visibleData = config.visibleData;
        }
        let cloneColumns = [];
        //顺序
        var sortDataKey = that.$utils.keys(config.sortData);
        if (config.sortData && sortDataKey.length > 0) {
          let sortArray = [];
          sortDataKey.forEach((key) => {
            sortArray.push({
              key: key,
              value: config.sortData[key],
            });
          });
          sortArray = that.$utils.orderBy(sortArray, "value");
          sortArray.forEach((sort) => {
            var columnsFind = that.$utils.find(
              columns,
              (f) => f.field == sort.key
            );
            if (columnsFind) {
              cloneColumns.push(columnsFind);
            }
          });
          columns = cloneColumns;
          that.gridCustom.sortData = config.sortData;
        }
      }

      //是否显示序号
      if (option.style.seq) {
        columns.unshift({
          type: "seq",
          width: 60,
          fixed: "left",
          resizable: false,
          slots: {
            header: "seq",
            default: "seqdefalut",
          },
        });
      }

      if (option.style.select == "checkbox") {
        columns.unshift({
          type: "checkbox",
          width: 50,
          align: "center",
          fixed: "left",
          resizable: false,
          slots: {
            checkbox: "checkbox",
            header: "checkboxHeader",
          },
        });
      }

      return columns;
    },

    /**
     * 得到排序
     */
    initSorts() {
      //默认排序
      let option = this.publicJson;
      var defaultSort = [];
      option.sort.forEach((item) => {
        defaultSort.push({ field: item.key, order: item.sord });
      });
      return defaultSort;
    },

    /**
     * 列表数据
     */
    reloadData() {
      if (this.$refs.xGrid) this.$refs.xGrid.commitProxy("query");
    },

    /**
     * 初始化数据刷新
     */
    initDataInterval() {
      let that = this;
      let option = this.publicJson;
      if (option.style.refresh != 0 && !that.refreshDataInterval) {
        that.refreshDataInterval = setInterval(function () {
          that.reloadData();
        }, option.style.refresh * 1000);
      }
    },
    /**
     * 列宽改变
     * @param {*} param0
     */
    resizableChange({ column }) {
      if (this.mode == 1) {
        let option = this.publicJson;
        let data = option.field.data;
        var columnFilter = data.filter((f) => f.key == column.field);
        columnFilter[0].width = column.resizeWidth;
      }
    },

    /**
     * 发布调整后表格
     */
    resizableChangeSave() {
      let that = this;
      that.$message.loading("保存中,请稍等...", 0);
      viewPublic({
        zeroCodeId: this.zeroCodeId,
        publicJson: JSON.stringify(this.publicJson),
      }).then(function (result) {
        that.$message.destroy();
        if (result.code === that.eipResultCode.success) {
          that.$message.success(result.msg);
        } else {
          that.$message.error(result.msg);
        }
      });
    },

    /**
     * 按钮点击触发事件
     */
    buttonClick(data) {
      switch (data.type) {
        case this.eipZeroCodeSystemButton.add:
          this.add();
          break;
        case this.eipZeroCodeSystemButton.edit:
          this.edit();
          break;
        case this.eipZeroCodeSystemButton.delete:
          this.del();
          break;
        case this.eipZeroCodeSystemButton.copy:
          this.copy();
          break;
        default:
          this.buttonCustomClick(data.button);
          break;
      }
    },
    /**
     * 按钮点击触发事件
     */
    buttonCustomClick(button) {
      let that = this;
      selectTableRow(
        that.$refs.xGrid,
        function (rows) {
          //判断按钮类型
          that.worksheet.mode = that.eipZeroCodeWorkSheetMode.button;
          if (
            button.form.target ==
              that.eipZeroCodeFormSettingButtonFormTarget.now &&
            button.form.write ==
              that.eipZeroCodeFormSettingButtonFormWrite.field
          ) {
            that.worksheet.from = {
              zeroCodeId: that.zeroCodeId, //工作表
              key: null, //来源控件(用于区分双向关联才解析默认绑定)
              rowId: rows.map((m) => m.RowId).join(","), //来源数据RowId,从列表上来时为多个
              button: button, //来源按钮Id,有值则表示从按钮点击来
            };
          }
          that.worksheet.visible = true;
        },
        that,
        false
      );
    },
    /**
     * 添加
     */
    add() {
      this.worksheet.rowId = newGuid();
      this.worksheet.mode = this.eipZeroCodeWorkSheetMode.add;
      this.worksheet.from = {
        zeroCodeId: null, //工作表
        key: null, //来源控件(用于区分双向关联才解析默认绑定)
        rowId: null, //来源数据RowId,从列表上来时为多个，逗号分割
        button: null, //来源按钮Id,有值则表示从按钮点击来
      };
      this.worksheet.visible = true;
    },
    /**
     * 编辑
     */
    edit() {
      let that = this;
      selectTableRow(
        that.$refs.xGrid,
        function (row) {
          that.worksheet.rowId = row.RowId;
          that.worksheet.mode = that.eipZeroCodeWorkSheetMode.edit;
          that.worksheet.from = {
            zeroCodeId: null, //工作表
            key: null, //来源控件(用于区分双向关联才解析默认绑定)
            rowId: null, //来源数据RowId,从列表上来时为多个，逗号分割
            button: null, //来源按钮Id,有值则表示从按钮点击来
          };
          that.worksheet.visible = true;
        },
        that
      );
    },

    /**
     * 复制
     */
    copy() {
      let that = this;
      selectTableRow(
        that.$refs.xGrid,
        function (rows) {
          that.$loading.show({ text: "复制中..." });
          let ids = that.$utils.map(rows, (item) => item.RowId);
          copy({
            zeroCodeId: that.zeroCodeId,
            rowId: ids.join(","),
            title: that.settingJson.data.title,
          }).then((result) => {
            that.$loading.hide();
            if (result.code == that.eipResultCode.success) {
              that.reloadData();
              that.$message.success(result.msg);
            } else {
              that.$message.error(result.msg);
            }
          });
        },
        that,
        false
      );
    },

    /**
     * 删除确定
     */
    del() {
      let that = this;
      //提示是否删除
      selectTableRow(
        that.$refs.xGrid,
        function (rows) {
          deleteConfirm(
            that.eipMsg.delete,
            function () {
              that.$loading.show({ text: that.eipMsg.delloading });
              let ids = that.$utils.map(rows, (item) => item.RowId);
              del({
                zeroCodeId: that.zeroCodeId,
                id: ids.join(","),
              }).then((result) => {
                that.$loading.hide();
                if (result.code == that.eipResultCode.success) {
                  that.reloadData();
                  that.$message.success(result.msg);
                } else {
                  that.$message.error(result.msg);
                }
              });
            },
            that
          );
        },
        that,
        false
      );
    },

    /**
     * 转换类型
     * @param row
     * @param column
     */
    convertType(column) {
      var columnFind = this.$utils.find(
        this.columnJson,
        (f) => f.key == column.field
      );
      if (columnFind) {
        return columnFind.type;
      } else {
        switch (column.field) {
          case "CreateTime":
          case "UpdateTime":
            return "systime";
          case "CreateUser":
          case "UpdateUser":
            return "sysuser";
        }
      }
    },

    /**
     * 得到Options
     * @param column
     */
    getOptions(column) {
      return this.$utils.find(this.columnJson, (f) => f.key == column.field);
    },

    /**
     *
     * @param param0
     */
    cellStyle({ row }) {
      let that = this;
      let option = this.publicJson;

      var value = row[option.color.field];
      let columnJson = this.$utils.find(
        this.columnJson,
        (f) =>
          f.type == that.eipZeroCodeControl.radio && f.key == option.color.field
      );

      if (columnJson && value && JSON.parse(value).length > 0) {
        var valueJson = JSON.parse(value);
        //是否全部
        if (
          option.color.displayType == "all" ||
          (option.color.display.length > 0 &&
            option.color.display.includes(valueJson[0]))
        ) {
          var find = this.$utils.find(
            columnJson.options.options,
            (f) => f.value == valueJson[0]
          );
          var backgroundColor = this.getLightColor(find.color, 0.8);
          return {
            backgroundColor: [1, 2].includes(option.color.showType)
              ? backgroundColor
              : "",
            showTypeColor: find.color,
            showType: option.color.showType,
          };
        }
      }
    },

    /**
     * 颜色变浅
     * @param color
     * @param level
     */
    getLightColor(color, level) {
      const hexToRgb = (str) => {
        let hexs = null;
        let reg = /^\#?[0-9A-Fa-f]{6}$/;
        if (!reg.test(str)) return alert("色值不正确");
        str = str.replace("#", ""); // 去掉#
        hexs = str.match(/../g); // 切割成数组 409EFF => ['40','9E','FF']
        // 将切割的色值转换为16进制
        for (let i = 0; i < hexs.length; i++) hexs[i] = parseInt(hexs[i], 16);
        return hexs; // 返回rgb色值[64, 158, 255]
      };
      const rgbToHex = (r, g, b) => {
        let reg = /^\d{1,3}$/; // 限定1-3位 -> 0~255
        if (!reg.test(r) || !reg.test(g) || !reg.test(b))
          return alert("色值不正确");
        let hex = [r.toString(16), g.toString(16), b.toString(16)];
        // 转换的值如果只有一位则补0
        for (let i = 0; i < 3; i++) {
          if (hex[i].length === 1) hex[i] = `0${hex[i]}`;
        }
        return `#${hex.join("")}`; // #409eff
      };
      let reg = /^\#?[0-9A-Fa-f]{6}$/;
      if (!reg.test(color)) return alert("色值不正确");
      let rgb = hexToRgb(color);
      // 循环对色值进行调整
      for (let i = 0; i < 3; i++) {
        rgb[i] = Math.floor((255 - rgb[i]) * level + rgb[i]); // 始终保持在0-255之间
      }
      return rgbToHex(rgb[0], rgb[1], rgb[2]); // [159, 206, 255]
    },
  },
};
</script>

<style lang="less" scoped>
.ant-tag {
  border-radius: 40px !important;
}
.colorTag {
  height: 22px;
  width: 4px;
  border-radius: 3px;
}
.img {
  width: 23px;
  height: 23px;
  border-radius: 50%;
}

/deep/ .run-list-user .ant-tag {
  cursor: pointer;
  padding: 0 7px 0 0 !important;
  border-radius: 50px !important;
}

/deep/ .run-list-user .ant-tag label {
  font-size: 12px;
  margin-left: 4px;
}
</style>
